package com.zhanghaijun.createCode.ad.factory;

import com.zhanghaijun.createCode.util.PrintUtil;
import com.zhanghaijun.createCode.util.PropsUtils;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.*;
import javax.naming.ldap.InitialLdapContext;
import java.util.Arrays;
import java.util.Hashtable;

/**
 * Created by zhanghaijun on 15/6/10.
 * ad连接工厂类
 */
public class AdConnectionFactory {

    private static DirContext ds = initSSLDirContext();//饿汉模式
    //private static DirContext dsBySSL = initSSLDirContext();
    private static String dcBase = PropsUtils.getProp("adDcBase");

    /**
     * 初始化LdapConnection
     * 非SSL 方式
     * @return
     */
    private static DirContext initDirContext() {
        DirContext ds = null;
        String providerUrl = PropsUtils.getProp("adServerHost");
        String principal = PropsUtils.getProp("adUserName");
        String credentials = PropsUtils.getProp("adPassword");
        Hashtable ldapEnv = new Hashtable();
        ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        ldapEnv.put(Context.PROVIDER_URL, providerUrl);
        ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
        ldapEnv.put(Context.SECURITY_PRINCIPAL, principal);
        ldapEnv.put(Context.SECURITY_CREDENTIALS, credentials); // 密码
        try {
            ds = new InitialLdapContext(ldapEnv, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ds;
    }


    private static DirContext initSSLDirContext(){
        DirContext ds = null;
        String keystore = "/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/security/cacerts";
        System.setProperty("javax.net.ssl.trustStore", keystore);
        System.setProperty("javax.net.ssl.trustStorePassword","changeit");
        //System.setProperty("javax.net.debug", "ssl,handshake");
        String providerUrl = PropsUtils.getProp("adServerHost");
        String principal = PropsUtils.getProp("adUserName");
        String credentials = PropsUtils.getProp("adPassword");
        Hashtable ldapEnv = new Hashtable();
        ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        ldapEnv.put(Context.PROVIDER_URL, providerUrl);
        ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");//(none,simple,strong)
        ldapEnv.put(Context.SECURITY_PRINCIPAL, principal);
        ldapEnv.put(Context.SECURITY_CREDENTIALS, credentials); // 密码
        ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
        try {
            ds = new InitialLdapContext(ldapEnv, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ds;
    }

    public static void add(String cn,String ou) {
        try{
            Attributes attrs = new BasicAttributes();
            attrs.put("displayName", "zhangsan");
            attrs.put("uid", cn);
            attrs.put("sn", cn);
            attrs.put("cn", cn);
            attrs.put("streetAddress", "12312312");
            attrs.put("sAMAccountName", cn);
            attrs.put("employeeId", cn);
            attrs.put("userPassword", "111111".getBytes());
            attrs.put("userPrincipalName", cn+"@testad.nb51");
            attrs.put("userAccountControl","544");
            attrs.put("pwdLastSet", "-1");

            String password="p123456qwe_@";
            String newQuotedPassword = "/" + password + "/";
            byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
            attrs.put("unicodePwd", newUnicodePassword);

            Attribute objclass = new BasicAttribute("objectClass");
            String[] attrObjectClassPerson = { "inetOrgPerson", "organizationalPerson", "person", "top","user"};
            Arrays.sort(attrObjectClassPerson);
            for (String ocp : attrObjectClassPerson) {
                objclass.add(ocp);
            }

            attrs.put(objclass);
            //dsBySSL.createSubcontext("cn="+cn+",ou="+ou+","+dcBase, attrs);
        }catch (Exception e){
            e.printStackTrace();
        }
    }







    /**
     * 单例获取实例入口
     * * @return
     */
    public static DirContext getDirContextInstance() {
        boolean isAlive = checkConnectionIsAlive();
        if(!isAlive){
            ds=initSSLDirContext();
        }
        return ds;
    }

    /**
     * 检查连接是否还活着
     * 需要做一次和ldap的交互
     * 根据资料显示一次搜索 来往的数据量最小
     */
    public static boolean checkConnectionIsAlive() {
        try {
            SearchControls searchCtls = new SearchControls();
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            String searchFilter = "(&(displayName=章海军))";
            String searchBase = dcBase;
            String returnedAtts[] = {"displayName"};
            searchCtls.setReturningAttributes(returnedAtts);
            NamingEnumeration<SearchResult> entries = ds.search(searchBase,
                    searchFilter, searchCtls);
            //PrintUtil.println(entries.hasMoreElements());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    public static void main(String[] args){
        PrintUtil.println(getDirContextInstance());
    }


}
